// controller  主要负责业务代码。为了后期的维护和新功能的增加，不建议把routes下的文件写的过于臃肿
const aboutModel = require('../models/about.js');
const aCategoryModel = require('../models/aboutCategory.js');
const url = require('url');

class AboutController {

    //关于我们分类的展示
    static getCategoryList=async (req, res) => {
        // 获取所有信息
        const infos=await aCategoryModel.find();
        res.render('aboutCategoryList', {title: '关于我们的分类展示',infos});
    };
    //关于我们分类的添加
    static getCategoryAdd=async (req,res)=>{
        res.render('aboutCategoryAdd',{title:'关于我们的分类添加',info:{}});
    };
    //关于我们分类的添加入库
    static AddCategoryPutInStore=async (req, res) => {
        let {cateName} = req.body;
        let cateObj = new aCategoryModel({cateName})
        let error = cateObj.validateSync();
        if (error) {
            // 如果有错误，将错误信息给用户
            const errorRs = [];
            for (let attr in error.errors) {
                errorRs.push(`${cateObj.fields[attr]}: ${error.errors[attr]}`);
            }
            //将错误信息返回给前台用户。单独封装一个错误页面 提示用户
            let url = 'admin/about/category/add';
            let time = 5;
            res.render('error', {errorRs, url, time});
            return;
        }
        // 信息合法
        try {
            let info = await cateObj.save();
            res.redirect('/admin/about/category/list');
        } catch (e) {
            res.redirect('/admin/about/category/add');
        }
    };
    //关于我们分类的删除
    static getCategoryDel=async (req, res) => {
        let cateId = req.params.id;
        try {
            await aCategoryModel.deleteOne({_id: cateId});
            res.redirect('back');
        }catch (e) {
            // 返回上一级
            res.redirect('back');
        }
    };
    //关于我们分类的编辑
    static getCategoryEdt=async(req,res)=>{
        let cateId=req.params.id;
        // 在编辑之前，先展示编辑内容的表单
        let info=await aCategoryModel.findOne({_id:cateId});
        res.render('aboutCategoryEdt',{title:'关于我们分类的编辑',info});
    };
    //关于我们分类的编辑入库
    static EdtCategoryPutInStore=async (req,res)=>{
        let {_id,cateName}=req.body;
        // 根据当前的id 去查找记录然后再更新
        aCategoryModel.findById(_id,async (error,doc)=>{
            if(error){
                res.redirect('back');
            }else{
                doc.cateName=cateName;
                await doc.save();
                res.redirect('/admin/about/category/list');
            }
        })
    };


    // 关于我们的分类详细信息列表的展示
    static getAboutList = async (req, res) => {
        /**
         * MongoDB提供了一个 limit(可以获取指定的条数)和skip（跳过多少条记录进行获取）
         * 利用这两个api可以完成分页功能
         * 分页原理：
         * 1、当前页
         * 2、当前页显示的数量
         * 3、总的记录数
         * 4、总共的页数：总记录数/每页显示的数量
         */
        let {page = 1, size = 3} = req.query;
        page = parseInt(page);
        size = parseInt(size);
        let count = await aboutModel.count();
        let offset = (page - 1) * size;
        let totalPage = Math.ceil(count / size);

        /* 使用mongoose里面的聚合操作，实现两张表之间的关联关系 */
        const infos = await aboutModel.aggregate([
            {
                $skip: offset
            },
            {
                $limit: size
            },
            {
                /* 这个是联表操作。现在将about表(cateId)和aboutCategory表(_id)产生联系 */
                $lookup: {
                    // 要关联的表
                    from: "aboutCategory",
                    // 自己表里面和别的表产生关系的id
                    localField: "cateId",
                    // 关联表的id
                    foreignField: "_id",
                    // 查询到的关联信息的key值
                    as: "cateInfo"
                }
            }]);
        res.render('aboutList', {page, size, count, totalPage, title: '关于我们详情-展示', infos});
    }
    //关于我们分类详情的添加
    static getAboutAdd = async (req, res) => {
        //获取所有分类信息
        const categoryInfo = await aCategoryModel.find();
        res.render('aboutAdd', {title: '关于我们详情-添加', info: {}, categoryInfo});
    }
    //关于我们的分类详情的编辑
    static getAboutEdt = async (req, res) => {
        let listId = url.parse(req.url, true).query.id;
        const categoryInfo = await aCategoryModel.find();
        // 在编辑之前，先展示编辑内容的表单
        let info = await aboutModel.findOne({_id: listId});
        res.render('aboutEdt', {title: '关于我们信息的编辑', info, categoryInfo});
    }
    //关于我们的分类详情的删除
    static getAboutDel = async (req, res) => {
        let listId = url.parse(req.url, true).query.id;
        try {
            await aboutModel.deleteOne({_id: listId});
            res.redirect('back');
        }catch (e) {
            // 返回上一级
            res.redirect('back');
        }
    }
    //信息编辑-入库
    static EdtPutInStore=async (req,res)=>{
        let {_id,cateId,description}=req.body;
        let pic = '';
        if(req.file){
            pic=req.file.filename;
        }
        // 根据当前的id 去查找记录然后再更新
        aboutModel.findById(_id,async (error,doc)=>{
            if(error){
                res.redirect('back');
            }else{
                doc.cateId=cateId;
                doc.description=description;
                doc.pic=pic;
                await doc.save();
                res.redirect('/admin/about/list');
            }
        })
    };
    //信息添加-入库
    static AddPutInStore=async (req, res) => {
        let {cateId,description}= req.body;
        let pic = '';
        if(req.file){
            pic=req.file.filename;
        }
        const aboutObj = new aboutModel({cateId,description,pic})
        let error = aboutObj.validateSync();
        if (error) {
            // 如果有错误，将错误信息给用户
            const errorRs = [];
            for (let attr in error.errors) {
                errorRs.push(`${aboutObj.fields[attr]}: ${error.errors[attr]}`);
            }
            //将错误信息返回给前台用户。单独封装一个错误页面 提示用户
            let url = 'admin/about/add';
            let time = 5;
            res.render('error', {errorRs, url, time});
            return;
        }
        // 信息合法
        try {
            let info = await aboutObj.save();
            res.redirect('/admin/about/list');
        } catch (e) {
            res.redirect('/admin/about/add');
        }
    };
}


module.exports = AboutController;